package com.tanhua.server.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.dubbo.server.api.TestSoulApi;
import com.tanhua.dubbo.server.enums.Cover;
import com.tanhua.dubbo.server.enums.Level;
import com.tanhua.dubbo.server.enums.QuestionnaireName;
import com.tanhua.dubbo.server.pojo.*;
import com.tanhua.server.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class TestSoulService {
    @Reference(version = "1.0.0")
    private TestSoulApi testSoulApi;

    @Autowired
    private UserInfoService userInfoService;

    /**
     * 将integer转为string
     *
     * @param integer
     * @return
     */
    private String returnLevelStr(Integer integer) {
        if (integer == 1) {
            return "初级";
        } else if (integer == 2) {
            return "中级";
        } else {
            return "高级";
        }
    }

    /**
     * 测灵魂-问卷列表（学生实战）
     *
     * @return
     */
    public List<QuestionnairesVo> queryQuestionnaire() {
        User user = UserThreadLocal.get();
        Long count = this.testSoulApi.countQuestionnaire(user.getId());
        if (0 == count){
            Questionnaire questionnaire1 = new Questionnaire();
            questionnaire1.setId(ObjectId.get());
            questionnaire1.setQuestionnaireNumber(String.valueOf(System.currentTimeMillis()));
            questionnaire1.setQuestionnaireName(QuestionnaireName.LOWERQN.getGrade());
            questionnaire1.setCoverUrl(Cover.LOWERURL.getUrl());
            questionnaire1.setLevel(Level.LOWER.getNumber());
            questionnaire1.setStar(2);
            questionnaire1.setIsLock(0);
            questionnaire1.setUserId(user.getId());
            questionnaire1.setUpdated(System.currentTimeMillis());
            this.testSoulApi.saveQuestionnaire(questionnaire1);

            Questionnaire questionnaire2 = new Questionnaire();
            questionnaire2.setId(ObjectId.get());
            questionnaire2.setQuestionnaireNumber(String.valueOf(System.currentTimeMillis()+1));
            questionnaire2.setQuestionnaireName(QuestionnaireName.MIDDLEQN.getGrade());
            questionnaire2.setCoverUrl(Cover.MIDDLEURL.getUrl());
            questionnaire2.setLevel(Level.MIDDLE.getNumber());
            questionnaire2.setStar(3);
            questionnaire2.setIsLock(1);
            questionnaire2.setUserId(user.getId());
            questionnaire2.setUpdated(System.currentTimeMillis());
            this.testSoulApi.saveQuestionnaire(questionnaire2);

            Questionnaire questionnaire3 = new Questionnaire();
            questionnaire3.setId(ObjectId.get());
            questionnaire3.setQuestionnaireNumber(String.valueOf(System.currentTimeMillis()+1));
            questionnaire3.setQuestionnaireName(QuestionnaireName.HIGHQN.getGrade());
            questionnaire3.setCoverUrl(Cover.HIGHURL.getUrl());
            questionnaire3.setLevel(Level.HIGH.getNumber());
            questionnaire3.setStar(5);
            questionnaire3.setIsLock(1);
            questionnaire3.setUserId(user.getId());
            questionnaire3.setUpdated(System.currentTimeMillis());
            this.testSoulApi.saveQuestionnaire(questionnaire3);

        }
        List<Questionnaire> questionnaires = this.testSoulApi.queryQuestionnaire(user.getId());
        //TODO 这里需要先判断下questionnaires是否为null,如果是null的话就给它新增数据，默认初级是开着的，中级和高级是锁着的
        List<QuestionnairesVo> questionnairesVos = new ArrayList<>();
        //对QuestionnairesVo进行封装
        for (Questionnaire questionnaire : questionnaires) {
            QuestionnairesVo questionnairesVo = new QuestionnairesVo();
            questionnairesVo.setId(questionnaire.getQuestionnaireNumber());
            questionnairesVo.setName(questionnaire.getQuestionnaireName());
            questionnairesVo.setCover(questionnaire.getCoverUrl());
            questionnairesVo.setLevel(returnLevelStr(questionnaire.getLevel()));
            questionnairesVo.setStar(questionnaire.getStar());
            List<Question> questions = this.testSoulApi.queryQuestionByLevel(questionnaire.getLevel());

            List<QuestionsVo> questionsVos = new ArrayList<>();
            for (Question question : questions) {
                QuestionsVo questionsVo = new QuestionsVo();
                questionsVo.setId(question.getQuestionNumber());
                questionsVo.setQuestion(question.getQuestionName());

                List<Option> options = this.testSoulApi.queryOptionByQuestionNumber(question.getQuestionNumber());

                List<OptionsVo> optionsVos = new ArrayList<>();
                for (Option option : options) {
                    OptionsVo optionsVo = new OptionsVo();
                    optionsVo.setId(option.getOptionNumber());
                    optionsVo.setOption(option.getOptionName());
                    optionsVos.add(optionsVo);
                }
                questionsVo.setOptions(optionsVos);
                questionsVos.add(questionsVo);
            }
            questionnairesVo.setQuestions(questionsVos);

            questionnairesVo.setIsLock(questionnaire.getIsLock());
            questionnairesVos.add(questionnairesVo);
        }
        return questionnairesVos;
    }


    /**
     * 测灵魂-提交问卷（学生实战）
     *
     * @param map
     * @return
     */
    public String saveTestResult(Map<String, List<TestSubmit>> map) {
        //解锁逻辑应该在这里完成，每次提交报告后将下一级问卷设为解锁，如果为高级题那就不用设置。
        User user = UserThreadLocal.get();

        Report report = new Report();
        report.setUserId(user.getId());

        try {
            List<TestSubmit> answers = map.get("answers");
            int sum = 0;
            for (TestSubmit answer : answers) {
                Integer integer = this.testSoulApi.queryOptionByQuestionNumAndOptionNum(answer.getQuestionId(), answer.getOptionId()).getScore();
                sum += integer;
            }

            report.setTotalScore(sum);

            //将结果插入到报告表中
            if (sum <= 21) {
                report.setType(1);
            } else if (sum <= 40) {
                report.setType(2);
            } else if (sum <= 55) {
                report.setType(3);
            } else {
                report.setType(4);
            }

            if (null == this.testSoulApi.queryReportByUserId(user.getId())) {

                //第一次做题，做了初级解锁中级。根据userId和level更新用户表
                Questionnaire questionnaire = new Questionnaire();
                questionnaire.setUserId(user.getId());
                questionnaire.setLevel(Level.MIDDLE.getNumber());
                questionnaire.setIsLock(0);
                //新测试用户用完后解锁中级关卡
                this.testSoulApi.updateQuestionnaire(questionnaire);

                Report report2 = this.testSoulApi.saveReport(report);
                return report2.getReportId();
            }

            report.setReportId(String.valueOf(System.currentTimeMillis()));
            report.setUpdated(System.currentTimeMillis());

            //判断当前测试题是不是中级题，是的话就解锁高级题
            //根据做的试题level来进行判断
            TestSubmit testSubmit = answers.get(0);

            Question question = this.testSoulApi.queryQuestionByQuestionNumber(testSubmit.getQuestionId());

            //做的是初级题
            if (1 == question.getLevel()){
                //根据用户id和level更新问卷表
                Questionnaire questionnaire = new Questionnaire();
                questionnaire.setUserId(user.getId());
                questionnaire.setLevel(Level.MIDDLE.getNumber());
                questionnaire.setIsLock(0);
                //如果做的是初级题，那么解锁中级关卡
                this.testSoulApi.updateQuestionnaire(questionnaire);
            }

            //做的是中级题
            if (2 == question.getLevel()){
                //根据用户id和level更新问卷表
                Questionnaire questionnaire = new Questionnaire();
                questionnaire.setUserId(user.getId());
                questionnaire.setLevel(Level.HIGH.getNumber());
                questionnaire.setIsLock(0);
                //如果做的是中级题，那么解锁高级关卡
                this.testSoulApi.updateQuestionnaire(questionnaire);
            }

            Report report3 = this.testSoulApi.updateReport(report);
            return report3.getReportId();
            //TODO没有记录执行插入，有记录，执行更新
        } catch (Exception e) {
            log.error("保存失败 userId = " + user.getId(), e);
        }
        return null;
    }

    /**
     * 测灵魂-查看结果（学生实战）
     *
     * @param reportId
     * @return
     */
    public TestResultVo queryTestResult(String reportId) {
        User user = UserThreadLocal.get();

        TestResultVo testResultVo = new TestResultVo();

        Report report = this.testSoulApi.queryReportById(reportId, user.getId());
        TestResult testResult = this.testSoulApi.queryTestResultByType(report.getType());//空指针异常

        testResultVo.setConclusion(testResult.getConclusion());
        testResultVo.setCover(testResult.getCover());

        List<Dimension> dimensions = this.testSoulApi.queryDimensionByType(report.getType());

        List<DimensionVo> dimensionVos = new ArrayList<>();
        for (Dimension dimension : dimensions) {
            DimensionVo dimensionVo = new DimensionVo();
            dimensionVo.setKey(dimension.getKey());
            dimensionVo.setValue(dimension.getValue());
            dimensionVos.add(dimensionVo);
        }

        testResultVo.setDimensions(dimensionVos);
        //TODO 这里最好是做一个分页展示。查5条，不足5条查到多少算多少
        //testResultVo.setSimilarYou(null);
        List<Report> reports = this.testSoulApi.queryReportByUserIdAndType(user.getId(), report.getType());

        List<SimilarYou> similarYous = new ArrayList<>();
        for (Report rp : reports) {
            //使用userInfoMapper
            SimilarYou similarYou = new SimilarYou();
            UserInfo userInfo = this.userInfoService.queryUserInfoByUserId(rp.getUserId());
            similarYou.setId(rp.getUserId());
            similarYou.setAvatar(userInfo.getLogo());
            similarYous.add(similarYou);
        }
        testResultVo.setSimilarYou(similarYous);
        return testResultVo;
    }
}
